package com.siemens.industrial.web.mvc.service.partner;

import com.siemens.industrial.model.partner.DeviceIdleInfo;
import com.siemens.industrial.model.partner.User;
import com.siemens.industrial.utils.GlobalResponseCode;
import com.siemens.industrial.utils.JsonToOtherFormat;
import com.siemens.industrial.utils.SiemensException;
import com.siemens.industrial.web.mvc.dao.partner.PartnerDeviceDao;
import com.siemens.industrial.web.mvc.dao.partner.PartnerDeviceIdleInfoDao;
import com.siemens.industrial.web.mvc.pojo.DataTableQuery;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by qupen on 2016/8/31.
 */
@Service
public class PartnerIdleService {
    @Resource
    PartnerDeviceIdleInfoDao partnerDeviceIdleInfoDao;

    @Resource
    PartnerDeviceDao partnerDeviceDao;

    @Resource
    JdbcTemplate jdbcTemplate;

    public Map getDeviceIdleInfo(String tenantId, String deviceId, String startTime) {
        Map info = partnerDeviceIdleInfoDao.getOneReason(tenantId, deviceId, startTime);
        if (info != null) {
            Map<String, Object> map = new HashMap<>();
            String reasonjson = info.get("meta_definition").toString();
            String key = info.get("meta_key").toString();
            String name = "无";
            String reason = "";
            if (info.get("user_name") != null) {
                name = info.get("user_name").toString();
            }
            if (key.equals("FaultType")) {
                reason = "FaultTypeReason";
            } else if (key.equals("IDLE")) {
                reason = "IDLEReason";
            }
            String infoReason = JsonToOtherFormat.buildJsonToMap(reasonjson).get(reason).toString();

            map.put("infoReason", infoReason);
            map.put("key", key);
            map.put("name", name);

            return map;
        }
        return null;
    }

    public List<DeviceIdleInfo> getDeviceIdleInfoList(String tenantId) {
        return partnerDeviceIdleInfoDao.getDeviceIdleInfoList(tenantId);
    }

    @Transactional
    public int saveDeviceIdleInfo(String tenantId, Map map, User user) throws SiemensException {
        if (partnerDeviceIdleInfoDao.getDeviceIdleInfo(tenantId, map.get("deviceId").toString(), map.get("startTime").toString()) == null) {

            if (map.get("endTime").toString().split(" ")[1].equals("24:00:00")) {
                SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                try {
                    Date time = format.parse(map.get("endTime").toString());
                    map.put("endTime", format.format(time));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }

            return partnerDeviceIdleInfoDao.saveDeviceIdleInfo(tenantId, map, user.getUserId());
        } else {
            throw new SiemensException(GlobalResponseCode.ERROR_IDLE_EXISTED);
        }
    }

    @Transactional
    public void updateDeviceIdleInfo(String tenantId, String deviceId, String startTime, Map<String, Object> data) throws SiemensException {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date startDate = null;
        try {
            startDate = dateFormat.parse(startTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        DeviceIdleInfo deviceIdleInfo = partnerDeviceIdleInfoDao.getDeviceIdleInfoByDeviceIdAndStartTime(tenantId, deviceId, startDate.getTime() / 1000);
        if (deviceIdleInfo == null)
            throw new SiemensException(GlobalResponseCode.ERROR_IDLE_EXISTED);
        deviceIdleInfo.setRepairInfo(JsonToOtherFormat.buildJsonToString(data));
        partnerDeviceIdleInfoDao.updateDeviceIdleInfo(tenantId, deviceIdleInfo);
    }

    public List<Map<String, Object>> getDeviceUniqueId(String database, String deviceType, String deviceModel) {
        return partnerDeviceDao.getDeviceUniqueIdByTypeAndModel(database, deviceType, deviceModel);
    }

    public List<String> getDeviceType(String database) {
        return partnerDeviceDao.getDeviceType(database);
    }

    public List<String> getDeviceModel(String database, String deviceType) {
        return partnerDeviceDao.getDeviceModelByType(database, deviceType);
    }

    public List<Map<String, Object>> getFaults(String tenantId) {
        List<Map<String, Object>> faultReasonList = partnerDeviceIdleInfoDao.getFaultReasonList(tenantId);
        for (Map<String, Object> faultReason : faultReasonList) {
            if (faultReason.get("repair_info") == null) {
                faultReason.put("repair_start_time", null);
                faultReason.put("repair_end_time", null);
                continue;
            }
            Map<String, Object> faultRepairInfo = JsonToOtherFormat.buildJsonToMap(faultReason.get("repair_info").toString());
            if (faultRepairInfo.containsKey("startTime")) {
                faultReason.put("repair_start_time", faultRepairInfo.get("startTime"));
            } else {
                faultReason.put("repair_start_time", null);
            }
            if (faultRepairInfo.containsKey("endTime")) {
                faultReason.put("repair_end_time", faultRepairInfo.get("endTime"));
            } else {
                faultReason.put("repair_end_time", null);
            }
        }
        return faultReasonList;
    }

    public List<Map<String, Object>> getDowntimeRecordList(String database) {
        return partnerDeviceDao.getDowntimeRecordList(database);
    }

    public List<Map<String, Object>> getAllMessage(String tenantId, String mtid, String startTime, String endTime, String idle, String status) {
        String sql = "select * from `" + tenantId + "`.message where 1=1";
        StringBuffer sb = new StringBuffer(sql);
        if (!mtid.equals("")) {
            sb.append(" and mtid = '" + mtid + "'");
        }
        if (!startTime.equals("")) {
            sb.append(" and start_time >= date('" + startTime + "')");
        }
        if (!endTime.equals("")) {
            sb.append(" and end_time <= date('" + endTime + "')");
        }
        if (!idle.equals("")) {
            sb.append(" and event_name = '" + idle + "'");
        }
        if (!status.equals("")) {
            sb.append(" and status = '" + Integer.parseInt(status) + "'");
        }

        String finallySql = sb.toString();
        return partnerDeviceDao.getMessages(finallySql);
    }

    public List getFaultType(String database) {
        List list = new ArrayList<>();
        List faultTypes = partnerDeviceIdleInfoDao.getFaultType(database);

        for (int i = 0; i < faultTypes.size(); i++) {
            Map map = new HashMap<>();
            String reasonJosn = ((Map) faultTypes.get(i)).get("meta_definition").toString();
            String faultType = JsonToOtherFormat.buildJsonToMap(reasonJosn).get("FaultTypeReason").toString();
            map.put("faultType", faultType);
            map.put("faultId", ((Map) faultTypes.get(i)).get("meta_id"));
            list.add(map);
        }
        return list;
    }

    public List getIdleReasons(String database) {
        List idleReasons = partnerDeviceIdleInfoDao.getIdleReasons(database);

        return jsonIdleToMap(idleReasons);
    }

    //idle json--map
    private List<Map<String, Object>> jsonIdleToMap(List<Map<String, Object>> idleReasons) {
        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < idleReasons.size(); i++) {
            Map map = new HashMap<>();
            String reasonjson = (String) ((Map) idleReasons.get(i)).get("meta_definition");
            String idleReason = (String) JsonToOtherFormat.buildJsonToMap(reasonjson).get("IDLEReason");
            map.put("idleName", idleReason);
            map.put("idleId", ((Map) idleReasons.get(i)).get("meta_id"));
            list.add(map);
        }
        return list;
    }

    //dataTable search faults
    public Map<String, Object> getFaultsByDataTable(String tenantId, HttpServletRequest request) {
        DataTableQuery dt = new DataTableQuery(request);
        List<Map<String, Object>> list = new ArrayList<>();

        String sql = "SELECT \n" +
                "    c.device_id,\n" +
                "    c.device_unique_id,\n" +
                "    b.start_time,\n" +
                "    b.end_time,\n" +
                "    b.repair_info,\n" +
                "    a.meta_definition\n" +
                "FROM\n" +
                "    `" + tenantId + "`.metadata a\n" +
                "        INNER JOIN\n" +
                "    `" + tenantId + "`.device_idle_info b ON a.meta_id = b.idle_reason\n" +
                "        INNER JOIN\n" +
                "    `" + tenantId + "`.device c ON b.device_id = c.device_id\n" +
                "WHERE\n" +
                "    a.meta_key = 'FaultType'\n";

        int total = jdbcTemplate.queryForList(sql).size();
        int filteredCount = total;

        if (!dt.getSearch().equals("")) {
            String search = " and (c.device_id like binary '%" + dt.getSearch() + "%' or c.device_unique_id like binary '%" + dt.getSearch() + "%' or b.start_time like binary '%" + dt.getSearch() + "%' or b.end_time like binary '%" + dt.getSearch() + "%' or b.repair_info like binary '%" + dt.getSearch() + "%' or a.meta_definition like binary '%" + dt.getSearch() + "%')";
            sql += search;
            filteredCount = jdbcTemplate.queryForList(sql).size();
        }

        if (!dt.getOrderDBColumn().equals("") && !dt.getOrderAscOrDesc().equals("")) {
            String order = " order by `" + dt.getOrderDBColumn() + "` " + dt.getOrderAscOrDesc();
            sql += order;
        }

        String limit = " limit " + dt.getStart() + "," + dt.getLength();
        sql += limit;
        list = jdbcTemplate.queryForList(sql);

//        List<Map<String, Object>> faultReasonList = partnerDeviceIdleInfoDao.getFaultReasonList(tenantId);
        for (Map<String, Object> faultReason : list) {
            if (faultReason.get("repair_info") == null) {
                faultReason.put("repair_start_time", null);
                faultReason.put("repair_end_time", null);
                continue;
            }
            Map<String, Object> faultRepairInfo = JsonToOtherFormat.buildJsonToMap(faultReason.get("repair_info").toString());
            if (faultRepairInfo.containsKey("startTime")) {
                faultReason.put("repair_start_time", faultRepairInfo.get("startTime"));
            } else {
                faultReason.put("repair_start_time", null);
            }
            if (faultRepairInfo.containsKey("endTime")) {
                faultReason.put("repair_end_time", faultRepairInfo.get("endTime"));
            } else {
                faultReason.put("repair_end_time", null);
            }
        }
        return dt.buildResponse(filteredCount, total, list);
    }

    public Map<String, Object> getAllMessageByDataTable(String tenantId, String mtid, String startTime, String endTime, String idle, String status, HttpServletRequest request) {
        DataTableQuery dt = new DataTableQuery(request);
        String sql = "select * from `" + tenantId + "`.message where 1=1";
        int total = jdbcTemplate.queryForList(sql).size();

        StringBuffer sb = new StringBuffer(sql);
        if (!mtid.equals("")) {
            sb.append(" and mtid = '" + mtid + "'");
        }
        if (!startTime.equals("")) {
            sb.append(" and start_time >= date('" + startTime + "')");
        }
        if (!endTime.equals("")) {
            sb.append(" and end_time <= date('" + endTime + "')");
        }
        if (!idle.equals("")) {
            sb.append(" and event_name = '" + idle + "'");
        }
        if (!status.equals("")) {
            sb.append(" and status = '" + Integer.parseInt(status) + "'");
        }

        if (!dt.getOrderDBColumn().equals("") && !dt.getOrderAscOrDesc().equals("")) {
            sb.append(" order by `" + dt.getOrderDBColumn() + "` " + dt.getOrderAscOrDesc());
        }

        sb.append(" limit " + dt.getStart() + "," + dt.getLength());

        String finallySql = sb.toString();
        String sql_user = "select a.*,b.user_name from (" + finallySql + ") a left join  `" + tenantId + "`.user b on a.user_id = b.user_id";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sql_user);
        return dt.buildResponse(list.size(), total, list);
    }
}
